#pragma once

#include <iostream>
#include <string>
// 给网络版本计算机定制协议--应用层

namespace protocol_ns
{
    #define HEADER_SEP "\r\n"
    // "长度"\r\n""_x _op _y"\r\n
    // "10 + 20" => "7"\r\n""10 + 20"\r\n => 报头 + 有效载荷
    // 请求/响应 = 报头\r\n有效载荷\r\n

    //为了服务器能够从TCP缓冲区中正确的读取到一个完整的string,我们就只能通过再添加协议报头的方式来保证
    std::string AddHeader(const std::string &str)
    {
        std::string s = std::to_string(str.size());
        s += HEADER_SEP;
        s += str;
        s += HEADER_SEP;
    }
    // "7"\r\n""10 + 20"\r\n => "10 + 20"
    std::string RemoveHeader(const std::string &str)
    {
        //?
    }


    // 请求和响应都需要支持序列化和反序列化
    // 服务器在接收到请求之后要对数据进行反序列话，以得到正确的数据，然后进行计算,客户端在收到一个请求之后也要对发送
    // 来的数据进行反序列化，以获得正确的服务端发送的响应信息
    // 服务器在发送一个响应的时候，需要先对响应信息进行序列化,为了网络传输需求
    // 客户端在发送信息的任务信息的时候，也因为同样的原因需要进行序列化

    class Request
    {
    public:
        Request() {}
        Request(int x, int y, char op) : _x(x), _y(y), _op(op)
        {
        }

        bool Serialize(std::string *outStr)
        {
            // 对输出参数做清空
            *outStr="";
            std::string x_string = std::to_string(_x);
            std::string y_string = std::to_string(_y);

            // 序列化---"10 + 3"  以空格作为分割
            *outStr = x_string + " " + _op + " " + y_string;

            return true;
        }

        bool Deserialize(const std::string &inStr)
        {
            std::string s = "";
            for (int i = 0; i < inStr.size(); ++i)
            {
                //"10 + 3"
                if (inStr[i] != ' ')
                {
                    if (inStr[i] == '+' || inStr[i] == '-' || inStr[i] == '*' || inStr[i] == '/' || inStr[i] == '%')
                    {
                        _op = inStr[i];
                    }
                    else
                        s += inStr[i];
                }
                else
                {
                    _x = stoi(s);
                    s.clear();
                }
            }
            _y = stoi(s);
        }

    public:
        int _x;
        int _y;
        char _op;
    };

    class Response
    {
    public:
        Response() {}
        Response(int result, int code)
            :_result(result), _code(code)
        {}

        bool Serialize(std::string *outStr)
        {
            //同样的套路
            *outStr="";
            std::string res_string = std::to_string(_result);
            std::string code_string = std::to_string(_code);

            //同样是以空格作为分隔符
            *outStr = res_string + " " + code_string;
            return true;
        }

        //"100 0"
        bool Deserialize(const std::string &inStr)
        {
            size_t n = inStr.find(' ');
            std::string str_res = inStr.substr(0, n);
            std::string str_cod = inStr.substr(n+1);

            _result = stoi(str_res);
            _code = stoi(str_cod);

            return true;
        }
    public:
        int _result;
        int _code; // 0 success, 1,2,3,4代表不同的错误码
    };
}